gusucode.com > VC++ 各种图形曲线绘制-源码程序 > VC++ 各种图形曲线绘制-源码程序/code/MyGL.cpp

    //Download by http://www.NewXing.com
// MyGL.cpp: implementation of the CMyGL class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "实验三.h"
#include "MyGL.h"
#include "Math.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMyGL::CMyGL()
{
	m_nPoint=0;
	m_Point[0].x=80;m_Point[0].y=300;
	m_Point[1].x=50;m_Point[1].y=200;
	m_Point[2].x=100;m_Point[2].y=50;
	m_Point[3].x=150;m_Point[3].y=150;
	
	m_Point[4].x=600;m_Point[4].y=20;
	m_Point[5].x=130;m_Point[5].y=260;
	m_Point[6].x=700;m_Point[6].y=260;
	m_Point[7].x=900;m_Point[7].y=40;
	m_nPoint=7;
}

CMyGL::~CMyGL()
{

}

void CMyGL::LineDDA2(int xa, int ya, int xb, int yb, CDC *pDC)
{
	int i;
	double dx,dy,lenght,x,y;
	if(fabs(xb-xa)>=fabs(yb-ya))
		lenght=fabs(xb-xa);
	else
		lenght=fabs(yb-ya);
	dx=(xb-xa)/lenght;
	dy=(yb-ya)/lenght;
	i=1;
	x=xa;
	y=ya;
	while(i<=lenght)
	{
		pDC->SetPixel(int(x+0.5),int(y+0.5),RGB(255,0,0));
		x+=dx;
		y+=dy;
		Sleep(1);
		i++;
	}
}

void CMyGL::MidPointEclipse(int xc, int yc, int a, int b, CDC *pDC)
{
	int aa=a*a,bb=b*b;
	int twoaa=2*aa,twobb=2*bb;
	int x=0,y=b;
	int d;
	int dx=0;
	int dy=twoaa*y;
	d=int(bb+aa*(-b+2.25)+0.5);
	pDC->SetPixel(xc+x,yc+y,RGB(255,0,0));
	pDC->SetPixel(xc+x,yc-y,RGB(255,0,0));
	pDC->SetPixel(xc-x,yc+y,RGB(255,0,0));
	pDC->SetPixel(xc-x,yc-y,RGB(255,0,0));
	while(dx<dy)
	{
		x++;
		dx+=twobb;
		if(d<0)
			d+=bb+dx;
		else
		{
			dy-=twoaa;
			d+=bb+dx-dy;
			y--;
		}
		Sleep(1);
		pDC->SetPixel(xc+x,yc+y,RGB(255,0,0));
		pDC->SetPixel(xc+x,yc-y,RGB(255,0,0));
		pDC->SetPixel(xc-x,yc+y,RGB(255,0,0));
		pDC->SetPixel(xc-x,yc-y,RGB(255,0,0));
	}
	d=int(bb*(x+0.5)*(x+0.5)+aa*(y-1)*(y-1)-aa*bb+0.5);
	while(y>0)
	{
		y--;
		dy-=twoaa;
		if(d>0)
			d+=aa-dy;
		else
		{
			x++;
			dx+=twobb;
			d+=aa-dy+dx;
		}
		Sleep(1);
		pDC->SetPixel(xc+x,yc+y,RGB(255,0,0));
		pDC->SetPixel(xc+x,yc-y,RGB(255,0,0));
		pDC->SetPixel(xc-x,yc+y,RGB(255,0,0));
		pDC->SetPixel(xc-x,yc-y,RGB(255,0,0));

	}
}

void CMyGL::LineBHM(int xa, int ya, int xb, int yb, CDC *pDC)
{
	int dx,dy,e,i,x,y;
	dx=xb-xa,dy=yb-ya,e=2*dy-dx;
	x=xa,y=ya;
	for(i=0;i<=dx;i++)
	{
		Sleep(1);
		pDC->SetPixel(x,y,RGB(255,0,0));
		x++;
		if(e>=0)
		{
			y++;
			e=e+2*dy-2*dx;
		}
		else
			e=e+2*dy;
	}
}

void CMyGL::MIDCIR(int sx, int sy, int r, CDC *pDC)
{
	int xx,yy;
	int e;
	xx=0;
	yy=r;
	e=1-r;
	CirclePoint(sx,sy,xx,yy,pDC);
	while(xx<=yy)
	{
		if(e<0)
			e+=2*xx+3;
		else
		{
			e+=2*(xx-yy)+5;
			yy--;
		}
		xx++;
		Sleep(1);
		CirclePoint(sx,sy,xx,yy,pDC);
	}
}

void CMyGL::CirclePoint(int x0, int y0, int x, int y, CDC *pDC)// 画圆的辅助函数
{
	/*以下显示不正常,原因在于坐标变换不正确,
	不能简单加负号,要用三角函数求出最终坐标值
	pDC->SetPixel(x,y,RGB(255,0,0));
	pDC->SetPixel(y,x,RGB(255,0,0));
	pDC->SetPixel(-x,y,RGB(255,0,0));
	pDC->SetPixel(y,-x,RGB(255,0,0));
	pDC->SetPixel(x,-y,RGB(255,0,0));
	pDC->SetPixel(-y,x,RGB(255,0,0));
	pDC->SetPixel(-x,-y,RGB(255,0,0));
	pDC->SetPixel(-y,-x,RGB(255,0,0));
	*/
	pDC->SetPixel(x0+x,y0+y,RGB(255,0,0));
    pDC->SetPixel(x0+y,y0+x,RGB(255,0,0));
    pDC->SetPixel(x0-x,y0+y,RGB(255,0,0));
    pDC->SetPixel(x0+y,y0-x,RGB(255,0,0));
    pDC->SetPixel(x0+x,y0-y,RGB(255,0,0));
    pDC->SetPixel(x0-y,y0+x,RGB(255,0,0));
    pDC->SetPixel(x0-x,y0-y,RGB(255,0,0));
    pDC->SetPixel(x0-y,y0-x,RGB(255,0,0));
}

void CMyGL::EdgeFlagFill(CRect &ClientRc, CPoint minpt, CPoint maxpt, CDC *pDC)
{
	int x,y;
	BOOL bPtIn;
	for(y=ClientRc.top+minpt.y;y<ClientRc.top+maxpt.x;y++)
	{
		bPtIn=FALSE;
		for(x=ClientRc.left+minpt.x;x<ClientRc.top+maxpt.x;x++)
		{
			if(pDC->GetPixel(x,y)==RGB(0,0,0))//边界默认颜色为黑色
			bPtIn=!bPtIn;
			if(bPtIn)
			{
				//Sleep(1);
				pDC->SetPixel(x,y,RGB(255,0,0));
			}
			else
				pDC->SetPixel(x,y,RGB(0,255,0));
		}
	}
}


void CMyGL::EdgeSeedFill(int x, int y, COLORREF fillcolor, COLORREF edgecolor,CDC *pDC)
{
	COLORREF current;
	current=pDC->GetPixel(x,y);
	if( (current!=fillcolor) && (current!=edgecolor) )
	{
		pDC->SetPixel(x,y,fillcolor);
		//Sleep(1);
		EdgeSeedFill(x,y+1,fillcolor,edgecolor,pDC);
		EdgeSeedFill(x,y-1,fillcolor,edgecolor,pDC);
		EdgeSeedFill(x+1,y,fillcolor,edgecolor,pDC);
		EdgeSeedFill(x-1,y,fillcolor,edgecolor,pDC);
	}
}

void CMyGL::BezierCurve(CDC *pDC)
{
	int i,j,nPoint;
	double tt;
	double step;
	CPen dotpen(PS_DOT,1,RGB(0,0,200)),*oldpen;
	CPen pen(PS_SOLID,1,RGB(0,0,0));
	CPoint *point=m_Point;	
	CPoint p[BEZIER_STEP+1];

	step=(double)1.0/(double)BEZIER_STEP;
	nPoint=m_nPoint;

	oldpen=pDC->SelectObject(&pen);
	while(nPoint>=4)
	{
		for(tt=0.0,j=0;tt<1.01;tt=tt+step,j++)
			p[j]=hor(3,point,tt);
		
		pDC->SelectObject(&dotpen);
		pDC->MoveTo(point[0].x,point[0].y);
		for(i=1;i<4;i++)
			pDC->LineTo(point[i].x,point[i].y);
	
		pDC->SelectObject(pen);
		pDC->MoveTo(p[0].x,p[0].y);
		for(i=1;i<j;i++)
			pDC->LineTo(p[i].x,p[i].y);
		nPoint-=3;
		point+=3;
	}
	pDC->SelectObject(oldpen);
}

CPoint CMyGL::hor(int degree, CPoint *point, double t)//BezierCurve的辅助函数hornbez()
{
	int i,choose_i;
	double fact,t1,x,y;
	CPoint aux;
	t1=1.0-t;
	fact=1.0;
	choose_i=1;
	x=(double)point[0].x*t1;
	y=(double)point[0].y*t1;
	for(i=1;i<degree;i++)
	{
		fact=fact*t;
		choose_i=choose_i*(degree-i+1)/i;
		x=(x+fact*choose_i*point[i].x)*t1;
		y=(y+fact*choose_i*point[i].y)*t1;
	}
	x=x+fact*t*(double)point[degree].x;
	y=y+fact*t*(double)point[degree].y;
	aux.x=(long)x;
	aux.y=(long)y;
	return aux;
}

void CMyGL::Move(UINT offx, UINT offy)//BezierCurve的辅助函数
{
	UINT i;
	for(i=0;i<m_nPoint;i++)
	{
		m_Point[i].x+=offx;
		m_Point[i].y+=offy;
	}
}

BOOL CMyGL::PtInBezier(CPoint point)//BezierCurve的辅助函数
{
	int i,j,nPoint;
	double tt;
	double step;
	CRect rec;
	int RecWidth=5;

	CPoint *pnt=m_Point;	
	CPoint p[BEZIER_STEP+1];

	step=(double)1.0/(double)BEZIER_STEP;
	nPoint=m_nPoint;

	while(nPoint>=4)
	{
		for(tt=0.0,j=0;tt<1.01;tt=tt+step,j++)
			p[j]=hor(3,pnt,tt);
		for(i=1;i<j;i++)
		{
			rec.left=p[i-1].x;
			rec.top=p[i-1].y;
			rec.right=p[i].x;
			rec.bottom=p[i].y;		
			rec.NormalizeRect();
			rec.InflateRect(1,1,1,1);
			if(PtInRect(&rec,point)) 
				return TRUE;
		}
		nPoint-=3;
		pnt+=3;
	}
	return FALSE;
}